Periodically gc repos in Cargo
authorAlex Crichton <alex@alexcrichton.com>
Sat, 9 Sep 2017 01:30:37 +0000 (18:30 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 14 Sep 2017 20:33:49 +0000 (13:33 -0700)
commitfe5a5c783fd7a39a0b68ea195ff4a62a12ea750c
tree74c5aa3e674c75b0eb639572cb28646c7f3a7792
parent98b6f6254e083647621b3ad2bf3628b79e5846fd
Periodically gc repos in Cargo

This commit is targeted at improving the long-term management of git checkouts
and git repositories. Currently every time data is fetched from crates.io
libgit2 will create a new pack file in the repository. These pack files
accumulate over time and end up causing pathological behavior if there's lots of
them, causing libgit2 to open many file descriptors all at once, possibly
blowing the system's file descriptor limits.

To alleviate this problem you typically run `git gc`, but libgit2 doesn't have
this implemented. Instead what Cargo now does is detect this situation and run
literally the command line tool `git gc` in a best-effort attempt to compact the
repo. Failing that, for example when git isn't installed, Cargo will remove the
entire repo and do a full checkout again.

At the same time this commit also generalizes this logic, plus the existing fast
path github logic, to all git repositories and not just the index. That way all
git repositories can benefit from the "github fast path" as well as the
compaction steps.

Closes #4403
src/cargo/sources/git/utils.rs
src/cargo/sources/registry/remote.rs
src/cargo/util/config.rs
src/cargo/util/lazy_cell.rs
tests/small-fd-limits.rs [new file with mode: 0644]